package core

import (
	"fmt"
	"gmfs/core/logger"
	"gmfs/core/web/handler"
	"gmfs/core/web/ink"
	"net/http"
	"os"
	"path"
	"runtime"
	"strings"
)

var (
	app *ink.App
)

func initApp(cfgJson string) {

	//初始化 app
	fmt.Printf("start %s.\n", ProName)
	app = ink.NewApp(cfgJson)
	handler.InitCache(app.Config().Bool("app.cache"))

	//初始化 log
	logger.Initialize(app.Config().StringOr("log.path", "./logs"), ProName)
	logger.SetConsole(app.Config().Bool("log.console"))
	level := logger.ConvLevel(app.Config().StringOr("log.level", "warn"))
	logger.SetLevel(level)

	//初始化 gridfs
	handler.InitGridfs(cfgJson)
	fmt.Printf("go version: %s\n", runtime.Version())
	fmt.Printf("giraffe version: %s\n", Version)

	//初始化 static
	initStatic()
}

/**
 * 启动服务
 */
func StartServer(cfgJson string) {

	//初始化
	initApp(cfgJson)

	app.Get("/", handler.Welcome)
	app.Get("/dispaly/:id/", handler.Dispaly)
	app.Get("/download/:id/", handler.Download)
	app.Get("/proxy/", handler.Proxy)
	app.Get("/online/:id/:rdm/", handler.Online)
	app.Post("/upload/", handler.Upload)
	app.Route("GET,POST", "/search/:md5/:size/", handler.Search)

	//演示 demo
	app.Get("/demo/", handler.Demo)
	app.Get("/api/", func(ctx *ink.Context) {
		ctx.Render("api", nil)
	})

	//set not found handler
	app.NotFound(func(ctx *ink.Context) {
		ctx.Body = []byte("not found!")
		ctx.End()
	})
	app.Run()
}

/**
 * 静态资源服务
 */
func initStatic() {
	app.Static(func(ctx *ink.Context) {
		static := app.Config().StringOr("app.static_dir", "core/web/static")
		url := strings.TrimPrefix(ctx.Url, "/")
		//资源文件
		if ctx.Ext == ".ico" || ctx.Ext == ".css" || ctx.Ext == ".js" {
			url = path.Join(static, url)
			//检查文件
			f, e := os.Stat(url)
			if e == nil {
				if f.IsDir() {
					ctx.Status = 403
					ctx.End()
					return
				}
			}

			_, e = os.Stat(url)
			if e != nil {
				ctx.Throw(404)
				return
			}
		} else if ctx.Ext == "" {
			//不支持无后缀访问
			ctx.Body = []byte("not support!")
			ctx.End()
			return
		} else {
			//返回 .html 请求
			return
		}

		http.ServeFile(ctx.Response, ctx.Request, url)
		ctx.IsEnd = true
	})
}
